﻿using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Logging;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Reflection;
using System.Text;
using VOL.Core.Configuration;
using VOL.Core.DBManager;
using VOL.Core.Extensions;
using VOL.Core.Infrastructure;
using VOL.Core.Services;
using VOL.Entity.DomainModels;

namespace VOL.Core.Utilities
{
    /// <summary>
    /// by huangxs 自定义的工具函数
    /// </summary>
    public class CustomHelper
    {

        /// <summary>
        /// 通用Excel导出功能
        /// </summary>
        /// <param name="rows"></param>
        /// <param name="fileName"></param>
        /// <param name="path"></param>
        /// <param name="onFillCell"></param>
        /// <param name="saveBefore"></param>
        /// <returns></returns>
        public static string ExportGeneralExcel<T>(
                List<T> rows,
                string fileName,
                string path = null)
        {
            path = path ?? $"Download/ExcelExport/{ DateTime.Now.ToString("yyyyyMMdd")}/";
            string fullPath = path.MapPath();
            fileName = Guid.NewGuid() + "_" + fileName;
            if (!Directory.Exists(fullPath)) Directory.CreateDirectory(fullPath);


            //List<PropertyInfo> propertyInfo = typeof(T).GetProperties().ToList();

            //Dictionary<string, object> dic = new Dictionary<string, object>();
            var heads = typeof(T).GetProperties()//获取表头字段和字段中文
                         .Where(p => p.IsDefined(typeof(DisplayAttribute), false))
                         .Select(p => new
                         {
                             PropertyName = p.Name,//字段名
                             ZhName = p.GetCustomAttributes(typeof(DisplayAttribute),
                            false).Cast<DisplayAttribute>().Single().Name//字段对应的中文名称
                         }).ToList();

            using (ExcelPackage package = new ExcelPackage())
            {

                var worksheet = package.Workbook.Worksheets.Add("sheet1");
                int cn = 1;
                foreach (dynamic col in heads)//取出表头对应的中文
                {
                    worksheet.Cells[1, cn].Value = col.ZhName;
                    cn++;
                }
                int j = 0;
                for (int i = 0; i < rows.Count; i++)
                {
                    T row = rows[i];
                    j = 0;
                    foreach (System.Reflection.PropertyInfo item in typeof(T).GetProperties())//循环取出泛型的属性值
                    {
                        object cellValue = item.GetValue(row, null);
                        worksheet.Cells[i + 2, j + 1].Value = cellValue;
                        j++;
                    }
                    worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();//自动填充单元格
                    for (var col = 1; col <= worksheet.Dimension.End.Column; col++)
                    {
                        worksheet.Column(col).Width = worksheet.Column(col).Width + 2;
                    }
                }
                package.SaveAs(new FileInfo(fullPath + fileName));
            }
            return path + fileName;
        }

        /// <summary>
        /// 防止零除
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static string linq_func_nozero(decimal a, decimal b)
        {

            string rtn = "";
            if (b == 0)
            {
                return "";
            }
            else
            {
                decimal c;
                c = Math.Round(a / b * 100, 2); //保留2为小数并转为百分比格式
                rtn = c.ToString() + "%";
            }
            ;
            return rtn;
        }


        /// <summary>
        /// 过滤HTML代码
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public static string checkStr(string html)
        {
            if (html is null) return "";
            System.Text.RegularExpressions.Regex regex1 =
                new System.Text.RegularExpressions.Regex(@"<script[\s\S]+</script *>",
                    System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex2 =
            new System.Text.RegularExpressions.Regex(@" href *= *[\s\S]*script *:",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex3 =
            new System.Text.RegularExpressions.Regex(@" no[\s\S]*=",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex4 =
            new System.Text.RegularExpressions.Regex(@"<iframe[\s\S]+</iframe *>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex5 =
            new System.Text.RegularExpressions.Regex(@"<frameset[\s\S]+</frameset *>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex6 =
            new System.Text.RegularExpressions.Regex(@"\<img[^\>]+\>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex7 =
            new System.Text.RegularExpressions.Regex(@"</p>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex8 =
            new System.Text.RegularExpressions.Regex(@"<p>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex regex9 =
            new System.Text.RegularExpressions.Regex(@"<[^>]*>",
            System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            html = regex1.Replace(html, ""); //过滤<script></script>标记 
            html = regex2.Replace(html, ""); //过滤href=javascript: (<A>) 属性 
            html = regex3.Replace(html, " _disibledevent="); //过滤其它控件的on...事件 
            html = regex4.Replace(html, ""); //过滤iframe 
            html = regex5.Replace(html, ""); //过滤frameset 
            html = regex6.Replace(html, ""); //过滤frameset 
            html = regex7.Replace(html, ""); //过滤frameset 
            html = regex8.Replace(html, ""); //过滤frameset 
            html = regex9.Replace(html, "");
            html = html.Replace(" ", "");
            html = html.Replace("</strong>", "");
            html = html.Replace("<strong>", "");
            return html;
        }

        /// <summary>
        /// 金额转换成中文大写金额
        /// </summary>
        /// <param name="LowerMoney">eg:10.74</param>
        /// <returns></returns>
        public static string MoneyToUpper(string LowerMoney)
        {
            string functionReturnValue = null;
            bool IsNegative = false; // 是否是负数
            if (LowerMoney.Trim().Substring(0, 1) == "-")
            {
                // 是负数则先转为正数
                LowerMoney = LowerMoney.Trim().Remove(0, 1);
                IsNegative = true;
            }
            string strLower = null;
            string strUpart = null;
            string strUpper = null;
            int iTemp = 0;
            // 保留两位小数 123.489→123.49　　123.4→123.4
            LowerMoney = Math.Round(double.Parse(LowerMoney), 2).ToString();
            if (LowerMoney.IndexOf(".") > 0)
            {
                if (LowerMoney.IndexOf(".") == LowerMoney.Length - 2)
                {
                    LowerMoney = LowerMoney + "0";
                }
            }
            else
            {
                LowerMoney = LowerMoney + ".00";
            }
            strLower = LowerMoney;
            iTemp = 1;
            strUpper = "";
            while (iTemp <= strLower.Length)
            {
                switch (strLower.Substring(strLower.Length - iTemp, 1))
                {
                    case ".":
                        strUpart = "圆";
                        break;
                    case "0":
                        strUpart = "零";
                        break;
                    case "1":
                        strUpart = "壹";
                        break;
                    case "2":
                        strUpart = "贰";
                        break;
                    case "3":
                        strUpart = "叁";
                        break;
                    case "4":
                        strUpart = "肆";
                        break;
                    case "5":
                        strUpart = "伍";
                        break;
                    case "6":
                        strUpart = "陆";
                        break;
                    case "7":
                        strUpart = "柒";
                        break;
                    case "8":
                        strUpart = "捌";
                        break;
                    case "9":
                        strUpart = "玖";
                        break;
                }

                switch (iTemp)
                {
                    case 1:
                        strUpart = strUpart + "分";
                        break;
                    case 2:
                        strUpart = strUpart + "角";
                        break;
                    case 3:
                        strUpart = strUpart + "";
                        break;
                    case 4:
                        strUpart = strUpart + "";
                        break;
                    case 5:
                        strUpart = strUpart + "拾";
                        break;
                    case 6:
                        strUpart = strUpart + "佰";
                        break;
                    case 7:
                        strUpart = strUpart + "仟";
                        break;
                    case 8:
                        strUpart = strUpart + "万";
                        break;
                    case 9:
                        strUpart = strUpart + "拾";
                        break;
                    case 10:
                        strUpart = strUpart + "佰";
                        break;
                    case 11:
                        strUpart = strUpart + "仟";
                        break;
                    case 12:
                        strUpart = strUpart + "亿";
                        break;
                    case 13:
                        strUpart = strUpart + "拾";
                        break;
                    case 14:
                        strUpart = strUpart + "佰";
                        break;
                    case 15:
                        strUpart = strUpart + "仟";
                        break;
                    case 16:
                        strUpart = strUpart + "万";
                        break;
                    default:
                        strUpart = strUpart + "";
                        break;
                }

                strUpper = strUpart + strUpper;
                iTemp = iTemp + 1;
            }

            strUpper = strUpper.Replace("零拾", "零");
            strUpper = strUpper.Replace("零佰", "零");
            strUpper = strUpper.Replace("零仟", "零");
            strUpper = strUpper.Replace("零零零", "零");
            strUpper = strUpper.Replace("零零", "零");
            strUpper = strUpper.Replace("零角零分", "整");
            strUpper = strUpper.Replace("零分", "整");
            strUpper = strUpper.Replace("零角", "零");
            strUpper = strUpper.Replace("零亿零万零圆", "亿圆");
            strUpper = strUpper.Replace("亿零万零圆", "亿圆");
            strUpper = strUpper.Replace("零亿零万", "亿");
            strUpper = strUpper.Replace("零万零圆", "万圆");
            strUpper = strUpper.Replace("零亿", "亿");
            strUpper = strUpper.Replace("零万", "万");
            strUpper = strUpper.Replace("零圆", "圆");
            strUpper = strUpper.Replace("零零", "零");

            // 对壹圆以下的金额的处理
            if (strUpper.Substring(0, 1) == "圆")
            {
                strUpper = strUpper.Substring(1, strUpper.Length - 1);
            }
            if (strUpper.Substring(0, 1) == "零")
            {
                strUpper = strUpper.Substring(1, strUpper.Length - 1);
            }
            if (strUpper.Substring(0, 1) == "角")
            {
                strUpper = strUpper.Substring(1, strUpper.Length - 1);
            }
            if (strUpper.Substring(0, 1) == "分")
            {
                strUpper = strUpper.Substring(1, strUpper.Length - 1);
            }
            if (strUpper.Substring(0, 1) == "整")
            {
                strUpper = "零圆整";
            }
            functionReturnValue = strUpper;

            if (IsNegative == true)
            {
                return "负" + functionReturnValue;
            }
            else
            {
                return functionReturnValue;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"> @"Template//cutomer_print_template//hktzs_print//hktzs_template.html";</param>
        /// <returns></returns>
        public static string read_local_file(string path)
        {
            string rtnstr = "";
            string filepath = path;
            string temp = filepath.MapPath().ReplacePath();
            UTF8Encoding utf8 = new UTF8Encoding();
            StreamReader file = null;
            try
            {
                file = new StreamReader(temp, utf8);
                //Console.WriteLine(temp);
                rtnstr = file.ReadToEnd();
            }
            catch//一定要释放，否则再次写入不了
            {
                file.Close();
                file.Dispose();
            }
            return rtnstr;
        }
        /// <summary>
        /// 删除逗号字符串
        /// d_str="string1,string2,string3";
        /// del_str="string2";
        /// 返回"string1,string3"
        /// </summary>
        /// <param name="d_str">原字符串</param>
        /// <param name="del_str">需要删除的字符串</param>
        /// <returns></returns>
        public static string del_string_dou(string d_str,string del_str)
        {
            //string rtn = "";
            string a = d_str;
            string b = del_str;
            List<string> a_arr = a.Split(",").ToList();
            a_arr = a_arr.Where(t => !t.Equals(b)).ToList();
            string c = "";
            c = String.Join(",", a_arr.ToArray());
            return c;
        }
        /// <summary>
        /// 删除重复字符串
        /// string d_str = "梵蒂冈,7,8,7";
        /// 返回字符串 "梵蒂冈,7,8"
        /// </summary>
        /// <param name="d_str"></param>
        /// <returns></returns>
        public static string del_rep_str_dou(string d_str)
        {
           
            return String.Join(",",d_str.Split(",").GroupBy(p => p).Select(p => p.Key).ToArray()); ;
        }

        public static string GetClientUserIp()
        {
            var ip = HttpContext.Current.Request.Headers["X-Real-IP"].ToString();
           
            Logger.Info("X-Real-IPoooo" + ip);
            Logger.Info("X-Forwarded-Foroooo" + HttpContext.Current.Request.Headers["X-Forwarded-For"].ToString());
            if (string.IsNullOrEmpty(ip))
            {
                ip = HttpContext.Current.Request.Headers["X-Forwarded-For"].ToString();
                //Logger.Info("X-Forwarded-Foroooo" + ip);
            }
            if (string.IsNullOrEmpty(ip))
            {
                ip = HttpContext.Current.Connection.RemoteIpAddress.ToString();
            }

            /* var request = HttpContext.Current.Request;
             string ip = request.Headers["X-Forwarded-For"];
             Logger.Info("X-Forwarded-For===" + ip);
             if (string.IsNullOrEmpty(ip) || string.Equals("unknown", ip, StringComparison.OrdinalIgnoreCase))
             {
                 ip = request.Headers["X-Real-IP"];
             }
             Logger.Info("X-Real-IP===" + ip);
             if (string.IsNullOrEmpty(ip) || string.Equals("unknown", ip, StringComparison.OrdinalIgnoreCase))
             {
                 ip = request.Headers["WL-Proxy-Client-IP"];
             }
             //ip=HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ??
             //   HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"] ?? "";

             if (string.IsNullOrEmpty(ip) || string.Equals("unknown", ip, StringComparison.OrdinalIgnoreCase))
             {
                 ip = HttpContext.Current.Connection.RemoteIpAddress.ToString();
             }
             *//*if (string.IsNullOrEmpty(ip))
             {
                 return string.Empty;
             }*/
            return ip.Replace("::ffff:", ""); ;
        }


    }
}
